package com.rgs.platform.test;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;
import com.rgs.base.core.statics.CaseFormatStaticClass;
import com.rgs.base.database.sql.ISqlFilter;
import com.rgs.base.database.sql.LikeTypeEnum;
import com.rgs.base.database.sql.SqlConditionEnum;
import com.rgs.base.database.sql.SqlFilterBetweenBO;
import tk.mybatis.mapper.entity.Example;

import java.lang.reflect.Field;
import java.util.Objects;

/**
 * @program: com-rgs-parent
 * @description:
 * @author: Mr.Ren
 * @create: 2022-12-14 16:29
 **/
public class RgsSqlUtil {
    private RgsSqlUtil() {
    }

    private static final String FULL_LIKE_STRING = "%{}%";
    private static final String AFTER_LIKE_STRING = "{}%";

    public static String fullLike(String para) {
        return StrUtil.format(FULL_LIKE_STRING, para);
    }

    public static String afterLike(String para) {
        return StrUtil.format(AFTER_LIKE_STRING, para);
    }

    /**
     * 根据实体对象和条件对象封装sql到Example对象中
     *
     * @param objClass 实体对象类
     * @param filter   条件对象
     * @param <T1>
     * @param <T2>
     * @return Example对象
     */
    public static <T1, T2 extends ISqlFilter> Example joinSql(Class<T1> objClass, T2 filter) {
        Example example = new Example(objClass);
        Example.Criteria criteria = example.createCriteria();
        Class<? extends ISqlFilter> filterClass = filter.getClass();
        //反射获取所有对象属性（包括父类的）
        //Field[] fields = filterClass.getFields();
        Field[] fields = ReflectUtil.getFields(filter.getClass());
        for (Field field : fields) {
            RgsSqlAnno annotation = field.getAnnotation(RgsSqlAnno.class);
            if (Objects.isNull(annotation)) {
                continue;
            }
            //反射时禁止安全检查
            field.setAccessible(true);
            Object objValue = null;
            try {
                //获取属性的值
                objValue = field.get(filter);
            } catch (IllegalAccessException e) {
                e.printStackTrace();
                continue;
            }
            if (Objects.isNull(objValue)) {
                continue;
            }
            String columnName;
            LikeTypeEnum likeTypeEnum;
            //动态条件判断
            if (annotation.customConditions().length > 0 && objValue instanceof Integer) {
                criteria.andCondition(annotation.customConditions()[(Integer) objValue]);
                continue;
            }
            columnName = annotation.columnName();
            likeTypeEnum = annotation.likeType();
            //拼接条件
            sqlFilterJoinOne(criteria, objValue, columnName, likeTypeEnum, annotation.sqlCondition());

            //拼接排序
            if (StrUtil.isNotEmpty(filter.getOrderByClause())) {
                example.setOrderByClause(filter.getOrderByClause());
            }

        }
        return example;
    }

    /**
     * 将字段拼接sql
     *
     * @param criteria         条件对象
     * @param objValue         条件值（可能是集合类型 字符串类型 SqlFilterBetweenBO类型）
     * @param columnName       数据库字段属性名
     * @param likeTypeEnum     模糊匹配方式
     * @param sqlConditionEnum sql条件（等于 大于 小于）
     */
    private static void sqlFilterJoinOne(Example.Criteria criteria,
                                         Object objValue,
                                         String columnName,
                                         LikeTypeEnum likeTypeEnum,
                                         SqlConditionEnum sqlConditionEnum) {
        switch (sqlConditionEnum) {
            //等于
            case EQUAL:
                if (objValue instanceof Iterable) {
                    if (CollUtil.isNotEmpty((Iterable) objValue)) {
                        criteria.andIn(columnName, (Iterable) objValue);
                    }
                } else if (objValue instanceof SqlFilterBetweenBO) {
                    SqlFilterBetweenBO sqlFilterBetweenBO = (SqlFilterBetweenBO) objValue;
                    criteria.andBetween(columnName, sqlFilterBetweenBO.getBegin(), sqlFilterBetweenBO.getEnd());
                } else if (objValue instanceof String) {
                    switch (likeTypeEnum) {
                        case NONE:
                            criteria.andEqualTo(columnName, objValue);
                            break;
                        case AFTER:
                            criteria.andLike(columnName, afterLike((String) objValue));
                            break;
                        default:
                            criteria.andLike(columnName, fullLike((String) objValue));
                            break;
                    }
                }
                break;
            //正则
            case REGULAR:
                if (StrUtil.isNotEmpty(objValue.toString())) {
                    columnName = CaseFormatStaticClass.CAMEL_TO_UNDERSCORE.convert(columnName);
                    criteria.andCondition(columnName.concat(" REGEXP "), objValue.toString());
                }
                break;
            //大于
            case GT:
                criteria.andGreaterThan(columnName, objValue);
                break;
            //小于
            case LT:
                criteria.andLessThan(columnName, objValue);
                break;
            //大于等于
            case GTEQ:
                criteria.andGreaterThanOrEqualTo(columnName, objValue);
                break;
            //小于等于
            case LTEQ:
                criteria.andLessThanOrEqualTo(columnName, objValue);
                break;
            default:
                break;
        }

    }


}
